/**
 * order of including header files is very important:
 * first #include "../inference/bchaining.hpp" 
 * below #include "kbase.hpp"
 */
#include "kbase.hpp"

namespace mashine { namespace kb {

KnowledgeBase::KnowledgeBase()
{
	rules = new std::vector<Rule *>();
	facts = new std::vector<Literal *>();
	analogies = new std::vector<Analogy *>();
		
	APP_LOGGER(info) << "KnowledgeBase instantiated";
}

KnowledgeBase::~KnowledgeBase()
{
	delete rules;
	delete facts;
	delete analogies;
	
	delete strategy;
	
	APP_LOGGER(info) << "KnowledgeBase is distracted";
}

/**
 * return current inference strategy
 */
mashine::inference::InferenceStrategy * KnowledgeBase::getInferenceStrategy() const
{
	return strategy;
}

/**
 * set new inference strategy
 *
 * param strategy - pointer to new inference strategy
 */
void KnowledgeBase::setInferenceStrategy(mashine::inference::InferenceStrategy * strategy)
{
	this->strategy = strategy;
}

/**
 * return result of search. after search visitor deleted
 *
 * param sVisitor - pointer to search visitor instance that realize
 * search algorithm, paramethers search set by constructor of visitor
 */
template<typename _KbEntity, typename _Criteria>
std::vector<_KbEntity *> * KnowledgeBase::advanceSearch(search::SearchVisitor<_KbEntity, _Criteria> * sVisitor) const
{
	std::vector<_KbEntity *> * resultSet = new std::vector<_KbEntity *>();
	resultSet = sVisitor->search(this);
		
	return sVisitor->search(this);
}

/**
 * realization delegate to inference strategy method
 *
 * param goal - goal of search
 *
 * return vector results of search of empty vector 
 */
std::vector<Literal *> KnowledgeBase::inference(std::vector<Literal *> const & goals) const
{
	strategy->inference(goals);
}

/**
 * this method call to add new rule
 * if rule alredy exist it ignored.
 * 
 * rule - add-on rule
 */
bool KnowledgeBase::add(Rule * rule)
{
	// TODO add validation
	rules->push_back(rule);
}

/**
 * this method call to add new fact
 * if fact alredy exist it ignored.
 * 
 * fact - add-on fact
 */
bool KnowledgeBase::add(Literal * fact)
{
	// TODO add validation
	facts->push_back(fact);
}

/**
 * this method call to add new analogy
 * if analogy alredy exist it ignored.
 * 
 * analogy - add-on analogy
 */
bool KnowledgeBase::add(Analogy * analogy)
{
	// TODO add validation
	analogies->push_back(analogy);
}

/**
 * return pointer to vector of pointers to rules
 */
std::vector<Rule *> * KnowledgeBase::getRules() const
{
	return rules;
}

/**
 * return pointer to vector of pointers to facts
 */
std::vector<Literal *> * KnowledgeBase::getFacts() const
{
	return facts;
}

/**
 * return pointer to vector of pointers to analogies
 */
std::vector<Analogy *> * KnowledgeBase::getAnalogies() const
{
	return analogies;
}

}}